<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
        <!-- <svg xmlns="http://www.w3.org/2000/svg" width='100%' height='600'></svg> -->
    <canvas width="1980" height="800"></canvas>
    <script src="d3.v4.min.js"></script>
    <script>
        const canvas = document.querySelector('canvas')
        ctx = canvas.getContext('2d')

        //定义坐标轴的位置
        const border_left = 80
        border_right = 80
        border_up = 80
        border_down = 80
        arrow_length = 20
        arrow_angle = Math.PI * (1/6)

        //获取画布大小
        const canavas_width = canvas.width
        canavas_height = canvas.height


       //设置背景
       const width = canvas.width
        height = canvas.height
        radius = 15

        const nodes = d3.range(30)
        .map((d,i)=>{
            return {
    x: Math.random() * (width - radius * 2) + radius,
    y: Math.random() * (height - radius * 2) + radius,
  }
        })

        const voronoi = d3.voronoi()
        .extent([[border_left,border_up],[width-border_right,height-border_down]])
        
        const data = nodes.map((d,i)=>{
            return [d.x,d.y]
        })

        const cell = voronoi(data)
        .polygons()

        console.log(cell);

        ctx.beginPath();
        cell.forEach(function(cell) { drawPolygon(cell); });
        ctx.lineWidth = 1.5;
        ctx.strokeStyle = "#DCDCDC";
        ctx.stroke();

        function drawPolygon(points) {
        ctx.moveTo(points[0][0], points[0][1]);
        for (var i = 1, n = points.length; i < n; ++i) ctx.lineTo(points[i][0], points[i][1]);
        ctx.closePath();
        }


        //画坐标轴

        //绘制X轴
        ctx.beginPath()
        ctx.moveTo(border_left,canavas_height - border_down)
        ctx.lineTo(border_left,border_up)
        ctx.lineTo(border_left-arrow_length*Math.sin(arrow_angle),border_up+arrow_length*Math.cos(arrow_angle))
        ctx.moveTo(border_left,border_up)
        ctx.lineTo(border_left+arrow_length*Math.sin(arrow_angle),border_up+arrow_length*Math.cos(arrow_angle))

        ctx.lineJoin = 'round'
        ctx.lineWidth = 2.5
        ctx.strokeStyle = '#8C8C88'
        ctx.stroke()

        //绘制Y轴
        ctx.beginPath()
        ctx.moveTo(border_left,canavas_height - border_down)
        ctx.lineTo(border_left+1300,canavas_height - border_down)
        ctx.lineTo(border_left+1300-arrow_length*Math.sin(arrow_angle),canavas_height - border_down-arrow_length*Math.sin(arrow_angle))
        ctx.moveTo(border_left+1300,canavas_height - border_down)
        ctx.lineTo(border_left+1300-arrow_length*Math.sin(arrow_angle),canavas_height - border_down+arrow_length*Math.sin(arrow_angle))

        ctx.lineJoin = 'round'
        ctx.lineWidth = 2.5
        ctx.strokeStyle = '#8C8C88'
        ctx.stroke()


       //封装画色块的函数
        function prt_block(location_x,location_y,highLoadHeight,normalLoadHeight){

            //色块的宽度
            const imgData_width = 25

            //色块位置
            // const location_x = 50
            // location_y = 50

            //根据高负载machine个数决定上部色块的高度
            // const highLoadHeight = 200

            //根据正常machine个数决定上部色块的高度   
            // const normalLoadHeight = 100

            //过渡色区的一半高度
            const transparency_half = 20

            const imgData_height = highLoadHeight+normalLoadHeight+2*transparency_half

            const imgData = ctx.createImageData(imgData_width,imgData_height)

            const transparency_up = d3.scaleLinear()
            .domain([imgData.data.length*(highLoadHeight/imgData_height),imgData.data.length*((highLoadHeight+transparency_half)/imgData_height)])
            .range([255,0])

            transparency_down = d3.scaleLinear()
            .domain([imgData.data.length*((highLoadHeight+transparency_half)/imgData_height),imgData.data.length*((highLoadHeight+transparency_half+transparency_half)/imgData_height)])
            .range([0,255])

            // console.log(imgData.data);//Uint8ClampedArray(40000) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, …]
            for(i=0;i<imgData.data.length*(highLoadHeight/imgData_height);i+=4){
                imgData.data[i+0] = 191
                imgData.data[i+1] = 71
                imgData.data[i+2] = 44
                imgData.data[i+3] = 255
            }

            for(i=imgData.data.length*(highLoadHeight/imgData_height);i<imgData.data.length*((highLoadHeight+transparency_half)/imgData_height);i+=4){
                imgData.data[i+0] = 191
                imgData.data[i+1] = 71
                imgData.data[i+2] = 44
                imgData.data[i+3] = transparency_up(i)
            }

            for(i=imgData.data.length*((highLoadHeight+transparency_half)/imgData_height);i<imgData.data.length*((highLoadHeight+transparency_half+transparency_half)/imgData_height);i+=4){
                imgData.data[i+0] = 242
                imgData.data[i+1] = 136
                imgData.data[i+2] = 75
                imgData.data[i+3] = transparency_down(i)
            }

            for(i=imgData.data.length*((highLoadHeight+transparency_half+transparency_half)/imgData_height);i<imgData.data.length;i+=4){
                imgData.data[i+0] = 242
                imgData.data[i+1] = 136
                imgData.data[i+2] = 75
                imgData.data[i+3] = 255
            }
            ctx.putImageData(imgData,location_x,location_y)

       }

       //测试函数，分别代表色块位置xy，高负载节点和正常节点
       let x1 = 80
       const intervel = 200
       let x = x1+intervel

       prt_block(x,2*border_up,200,100)
       prt_block(x+=intervel,2*border_up,200,361)
       prt_block(x+=intervel,3*border_up,300,480)
       prt_block(x+=intervel,2*border_up,150,666)
       prt_block(x+=intervel,3*border_up,600,52)

    </script>
</body>
</html>